package cn.edu.fzu.delivery.controller;

import cn.edu.fzu.delivery.common.RedisClient;
import cn.edu.fzu.delivery.common.RedisKey;
import cn.edu.fzu.delivery.common.Result;
import cn.edu.fzu.delivery.domain.entity.Customer;
import cn.edu.fzu.delivery.domain.enums.SexEnum;
import cn.edu.fzu.delivery.exception.ServiceException;
import cn.edu.fzu.delivery.helper.EmailHelper;
import cn.edu.fzu.delivery.helper.VcodeHelper;
import cn.edu.fzu.delivery.service.UserService;
import cn.edu.fzu.delivery.session.SessionConstant;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

/**
 * 注册
 *
 * @author fangxin
 * @date 2022/11/11
 */
@RestController
@RequestMapping("/api")
@Api(tags = "注册服务")
public class RegisterController {

    //邮箱正则校验
    private static final String      EMAIL_REGEX    = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$";
    //手机号正则校验
    private static final String      PHONE_REGEX    = "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$";
    //姓名正则校验,2-4个中文字符
    private static final String      NAME_REGEX     = "^[\\u4e00-\\u9fa5]{2,4}$";
    //密码校验,至少8位，包含大小写字母、数字以及特殊字符
    private static final String      PASSWORD_REGEX = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[$@$!%*?&.+-])[A-Za-z\\d$@$!%*?&.+-]{8,}";
    private static final VcodeHelper codeHelper     = new VcodeHelper(5);

    @Resource
    private EmailHelper              emailHelper;
    @Resource
    private UserService              userService;

    @ApiOperation(value = "获取邮箱验证码", httpMethod = "GET")
    @ApiImplicitParams({ @ApiImplicitParam(name = "email", value = "邮箱") })
    @GetMapping("/sendEmailCode")
    public Result sendEmailCode(String email, HttpServletRequest request) {
        if (StringUtils.isBlank(email) || !Pattern.compile(EMAIL_REGEX).matcher(email).matches()) {
            throw new ServiceException("请正确填写邮箱");
        }
        String code = codeHelper.generatorVCode();
        if (!emailHelper.sendMail(email, "邮箱验证码", "您的此次验证码为：" + code + ",有效时长为30分钟")) {
            throw new ServiceException("邮箱发送失败，请检查邮箱是否填写正确");
        }
        request.getSession().setAttribute(email, code);
        return Result.SUCCESS;
    }


    @ApiOperation(value = "顾客注册", httpMethod = "POST")
    @ApiImplicitParams({ @ApiImplicitParam(name = "email", value = "邮箱"),
            @ApiImplicitParam(name = "code", value = "邮箱验证码"), @ApiImplicitParam(name = "password", value = "密码"),
            @ApiImplicitParam(name = "rePassword", value = "再次输入密码"),
            @ApiImplicitParam(name = "phone", value = "手机号码") })
    @PostMapping("/cusRegister")
    public Result register(@RequestParam String email, @RequestParam String code, @RequestParam String password,
                           String rePassword, @RequestParam String phone, HttpServletRequest request) {
        String emailCode = (String) request.getSession().getAttribute(email);
        if (!StringUtils.equalsIgnoreCase(emailCode, code)) {
            throw new ServiceException("请填写正确的邮箱验证码");
        }
        if (!Objects.equals(password, rePassword)) {
            throw new ServiceException("两次填写的密码不相同");
        }
        if (!Pattern.compile(PASSWORD_REGEX).matcher(password).matches()) {
            throw new ServiceException("密码至少8位，包含大小写字母、数字以及特殊字符");
        }
        if (!Pattern.compile(PHONE_REGEX).matcher(phone).matches()) {
            throw new ServiceException("请正确填写手机号，否则可能无法正常寄取快递");
        }
        userService.addCustomer(email, password, null, null, null, phone, null);
        return Result.SUCCESS;
    }


    @ApiOperation(value = "顾客完善信息", httpMethod = "POST")
    @ApiImplicitParams({ @ApiImplicitParam(name = "name", value = "姓名"), @ApiImplicitParam(name = "sex", value = "性别"),
            @ApiImplicitParam(name = "birth", value = "出生年月"), @ApiImplicitParam(name = "imageUrl", value = "照片") })
    @PostMapping("/auth/customer/completeInfo")
    public Result completeInfo(String name, SexEnum sex, String birth, String imageUrl, HttpServletRequest request) {
        Customer customer = (Customer) request.getSession().getAttribute(SessionConstant.DELIVERY_ACCOUNT);
        if (!Pattern.compile(NAME_REGEX).matcher(name).matches()) {
            throw new ServiceException("请正确填写姓名");
        }
        userService.updateCustomer(customer.getId(), name, sex, birth, imageUrl);
        return Result.SUCCESS;
    }


    @ApiOperation(value = "顾客修改密码", httpMethod = "POST")
    @ApiImplicitParams({ @ApiImplicitParam(name = "email", value = "邮箱"),
            @ApiImplicitParam(name = "code", value = "邮箱验证码"), @ApiImplicitParam(name = "password", value = "密码"),
            @ApiImplicitParam(name = "rePassword", value = "再次输入密码") })
    @PostMapping("/cusUpdatePassword")
    public Result updatePassword(@RequestParam String email, @RequestParam String code, @RequestParam String password,
                                 @RequestParam String rePassword, HttpServletRequest request) {
        String emailCode = (String) request.getSession().getAttribute(email);
        if (!Objects.equals(emailCode, code)) {
            throw new ServiceException("请填写正确的邮箱验证码");
        }
        if (!Objects.equals(password, rePassword)) {
            throw new ServiceException("两次填写的密码不相同");
        }
        if (!Pattern.compile(PASSWORD_REGEX).matcher(password).matches()) {
            throw new ServiceException("密码至少8位，包含大小写字母、数字以及特殊字符");
        }
        userService.updateCustomerPassword(email, password);
        return Result.SUCCESS;
    }


    @ApiOperation(value = "系统用户修改密码", httpMethod = "POST")
    @ApiImplicitParams({ @ApiImplicitParam(name = "email", value = "邮箱", required = true),
            @ApiImplicitParam(name = "code", value = "邮箱验证码", required = true),
            @ApiImplicitParam(name = "password", value = "密码", required = true),
            @ApiImplicitParam(name = "rePassword", value = "再次输入密码", required = true) })
    @PostMapping("/sysUpdatePassword")
    public Result updateSysPassword(@RequestParam String email, @RequestParam String code,
                                    @RequestParam String password, @RequestParam String rePassword,
                                    HttpServletRequest request) {
        String emailCode = (String) request.getSession().getAttribute(email);
        if (!Objects.equals(emailCode, code)) {
            throw new ServiceException("请填写正确的邮箱验证码");
        }
        if (!Objects.equals(password, rePassword)) {
            throw new ServiceException("两次填写的密码不相同");
        }
        if (!Pattern.compile(PASSWORD_REGEX).matcher(password).matches()) {
            throw new ServiceException("密码至少8位，包含大小写字母、数字以及特殊字符");
        }
        userService.updateSysPassword(email, password);
        return Result.SUCCESS;
    }
}
